home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
comm
/
term
/
term34Source.lha
/
termReviewBuffer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
35KB
|
1,797 lines
/*
** termReviewBuffer.c
**
** Support routines for the review buffer
**
** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* Menu item codes. */
enum { MEN_SEARCH,MEN_REPEAT,MEN_CLEARBUF,MEN_QUITBUF };
/* Gadget ID codes. */
enum { GAD_SCROLLER, GAD_UP, GAD_DOWN };
/* The arrow image height. */
#define ARROW_HEIGHT 11
STATIC struct NewMenu ReviewMenu[] =
{
{ NM_TITLE, NULL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_SEARCH},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_REPEAT},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_CLEARBUF},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_QUITBUF},
{ NM_END, 0, 0 , 0, 0, (APTR)0}
};
/* Local routines. */
STATIC VOID ReviewUpdatePot(VOID);
STATIC VOID __stdargs ReviewWrites(STRPTR String,...);
STATIC VOID __regargs PrintReviewLine(STRPTR Buffer,LONG Line);
STATIC VOID __regargs RefreshReview(LONG Top);
STATIC VOID __regargs ScrollReview(LONG Top);
STATIC BYTE ReviewQuery(VOID);
STATIC UBYTE __regargs GetReviewChar(BYTE WaitForIt);
/* Local variables. */
STATIC struct Menu *ReviewMenuStrip;
STATIC struct IBox ReviewBox;
STATIC struct IOStdReq *ReviewWriteRequest,
*ReviewReadRequest;
STATIC struct MsgPort *ReviewWritePort;
STATIC struct Gadget *Scroller,
*UpArrow,
*DownArrow;
STATIC UWORD RightBorderWidth;
STATIC struct Image *UpImage,
*DownImage;
STATIC UBYTE ReviewChar;
STATIC LONG ReviewColumns,ReviewLines,
ReviewTop = -1,ReviewGlobalLines;
STATIC struct SearchInfo *ReviewSearchInfo;
STATIC BYTE SearchForward = TRUE;
STATIC UBYTE *ReviewLineWidths;
STATIC LONG ReviewMaxLines;
/* SplitEventReport():
*
* Split a raw console input event report into components.
*/
STATIC VOID __regargs
SplitEventReport(STRPTR Buffer,LONG Len,UBYTE *Class,UWORD *Code,UWORD *Qualifier,ULONG *Prev)
{
STRPTR Start = Buffer;
LONG Count = 0;
if(Prev)
*Prev = NULL;
while(Len--)
{
if(*Buffer == ';')
{
*Buffer++ = 0;
switch(Count++)
{
case 0: *Class = Atol(Start);
break;
case 2: if(Code)
*Code = Atol(Start);
break;
case 3: if(Qualifier)
*Qualifier = Atol(Start);
break;
case 4: if(Prev)
*Prev = Atol(Start) << 16;
break;
case 5: if(Prev)
*Prev |= Atol(Start);
break;
}
Start = Buffer;
}
else
Buffer++;
}
}
/* ReviewDeleteScroller(VOID):
*
* Delete scroller and arrow buttons.
*/
STATIC VOID
ReviewDeleteScroller(VOID)
{
if(Scroller)
{
DisposeObject(Scroller);
Scroller = NULL;
}
if(UpArrow)
{
DisposeObject(UpArrow);
UpArrow = NULL;
}
if(DownArrow)
{
DisposeObject(DownArrow);
DownArrow = NULL;
}
if(UpImage)
{
DisposeObject(UpImage);
UpImage = NULL;
}
if(DownImage)
{
DisposeObject(DownImage);
DownImage = NULL;
}
}
/* ReviewCreateScroller(struct Screen *Screen):
*
* Create scroller and arrow buttons.
*/
STATIC BYTE __regargs
ReviewCreateScroller(struct Screen *Screen)
{
struct DrawInfo *DrawInfo;
BYTE Result = FALSE;
if(DrawInfo = GetScreenDrawInfo(Screen))
{
LONG SizeWidth,
SizeHeight;
UWORD SizeType;
if(Screen -> Flags & SCREENHIRES)
{
SizeWidth = 18;
SizeHeight = 10;
SizeType = SYSISIZE_MEDRES;
}
else
{
SizeWidth = 13;
SizeHeight = 11;
SizeType = SYSISIZE_LOWRES;
}
RightBorderWidth = SizeWidth;
if(UpImage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_Size, SizeType,
SYSIA_Which, UPIMAGE,
SYSIA_DrawInfo, DrawInfo,
TAG_DONE))
{
if(DownImage = (struct Image *)NewObject(NULL,"sysiclass",
SYSIA_Size, SizeType,
SYSIA_Which, DOWNIMAGE,
SYSIA_DrawInfo, DrawInfo,
TAG_DONE))
{
if(Scroller = NewObject(NULL,"propgclass",
GA_ID, GAD_SCROLLER,
GA_Top, Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
GA_RelHeight, -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ARROW_HEIGHT),
GA_Width, SizeWidth - 8,
GA_RelRight, -(SizeWidth - 5),
GA_Immediate, TRUE,
GA_FollowMouse, TRUE,
GA_RelVerify, TRUE,
GA_RightBorder, TRUE,
PGA_Freedom, FREEVERT,
PGA_NewLook, TRUE,
PGA_Borderless, TRUE,
PGA_Visible, 1,
PGA_Total, 1,
TAG_DONE))
{
STATIC struct TagItem ArrowMappings[] =
{
GA_ID, GA_ID,
TAG_END
};
if(UpArrow = NewObject(NULL,"buttongclass",
GA_ID, GAD_UP,
GA_Image, UpImage,
GA_RelRight, -(SizeWidth - 1),
GA_RelBottom, -(SizeHeight - 1 + 2 * ARROW_HEIGHT),
GA_Height, ARROW_HEIGHT,
GA_Width, SizeWidth,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_Previous, Scroller,
GA_RightBorder, TRUE,
ICA_TARGET, ICTARGET_IDCMP,
ICA_MAP, ArrowMappings,
TAG_DONE))
{
if(DownArrow = NewObject(NULL,"buttongclass",
GA_ID, GAD_DOWN,
GA_Image, DownImage,
GA_RelRight, -(SizeWidth - 1),
GA_RelBottom, -(SizeHeight - 1 + ARROW_HEIGHT),
GA_Height, ARROW_HEIGHT,
GA_Width, SizeWidth,
GA_Immediate, TRUE,
GA_RelVerify, TRUE,
GA_Previous, UpArrow,
GA_RightBorder, TRUE,
ICA_TARGET, ICTARGET_IDCMP,
ICA_MAP, ArrowMappings,
TAG_DONE))
Result = TRUE;
}
}
}
}
FreeScreenDrawInfo(Screen,DrawInfo);
}
return(Result);
}
/* ReviewUpdatePot():
*
* Update size and position of the scroller gadget.
*/
STATIC VOID
ReviewUpdatePot()
{
if(ReviewGlobalLines)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top, ReviewTop,
PGA_Visible, ReviewLines,
PGA_Total, ReviewGlobalLines,
TAG_DONE);
}
}
/* ReviewUp(LONG Count):
*
* Move the contents of the review buffer up.
*/
STATIC VOID __regargs
ReviewUp(LONG Count)
{
if(BufferLines)
{
if(Count == 1)
{
if(ReviewTop)
{
WORD i;
for(i = ReviewMaxLines - 2 ; i >= 0 ; i--)
ReviewLineWidths[i + 1] = ReviewLineWidths[i];
ReviewTop--;
ReviewWrites("\33[T");
ObtainSemaphore(BufferSemaphore);
PrintReviewLine(BufferLines[ReviewTop],1);
ReviewUpdatePot();
ReleaseSemaphore(BufferSemaphore);
}
}
else
{
LONG NewTop = ReviewTop;
if(NewTop >= Count)
NewTop -= Count;
else
NewTop = 0;
if(NewTop != ReviewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
}
}
}
/* ReviewDown(LONG Count):
*
* Move the contents of the review buffer down.
*/
STATIC VOID __regargs
ReviewDown(LONG Count)
{
if(BufferLines)
{
if(Count == 1)
{
if(ReviewTop + ReviewLines < Lines)
{
LONG Last;
WORD i;
for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
ReviewLineWidths[i] = ReviewLineWidths[i + 1];
ReviewTop++;
ReviewWrites("\33[S");
ObtainSemaphore(BufferSemaphore);
if((Last = ReviewTop + ReviewLines) < Lines)
PrintReviewLine(BufferLines[Last],ReviewLines + 1);
ReviewUpdatePot();
ReleaseSemaphore(BufferSemaphore);
}
}
else
{
LONG NewTop = ReviewTop;
if((NewTop + Count + ReviewLines) > Lines)
{
if((NewTop = Lines - ReviewLines) < 0)
NewTop = 0;
}
else
NewTop += Count;
if(NewTop != ReviewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
}
}
}
/* ReviewWrites(STRPTR String,...):
*
* Write a string into the review buffer window.
*/
STATIC VOID __stdargs
ReviewWrites(STRPTR String,...)
{
va_list VarArgs;
va_start(VarArgs,String);
VSPrintf(SharedBuffer,String,VarArgs);
va_end(VarArgs);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = SharedBuffer;
ReviewWriteRequest -> io_Length = -1;
DoIO(ReviewWriteRequest);
}
/* FilterReviewLine(register STRPTR Line,register LONG Length):
*
* Replace non-printable characters in the text line
* to be printed.
*/
STATIC STRPTR __regargs
FilterReviewLine(register STRPTR Line,register LONG Length)
{
STATIC UBYTE ISO[256] =
{
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
STATIC UBYTE TempBuffer[256];
register STRPTR Destination = TempBuffer;
while(Length--)
*Destination++ = ISO[*Line++];
return(TempBuffer);
}
/* PrintReviewLine(STRPTR Buffer,LONG Line):
*
* Write the contents of a buffer line into the review buffer window.
*/
STATIC VOID __regargs
PrintReviewLine(STRPTR Buffer,LONG Line)
{
WORD Length = Buffer[-1];
if(Length > ReviewColumns)
Length = ReviewColumns;
ReviewWrites("\33[%ldH",Line);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = FilterReviewLine(Buffer,Length);
ReviewWriteRequest -> io_Length = Length;
DoIO(ReviewWriteRequest);
if(Length < ReviewLineWidths[Line - 1])
ReviewWrites("\33[0K");
ReviewLineWidths[Line - 1] = Length;
}
/* RefreshReview(LONG Top):
*
* Refresh the contents of the review buffer window.
*/
STATIC VOID __regargs
RefreshReview(LONG Top)
{
LONG i,Last,Line = 0;
ObtainSemaphore(BufferSemaphore);
ReviewGlobalLines = Lines;
if((Last = Top + ReviewLines + 1) >= Lines)
{
Last = Lines;
if((Top = Last - ReviewLines) < 0)
Top = 0;
ReviewTop = Top;
}
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
PrintReviewLine(BufferLines[i],++Line);
}
if(Line <= ReviewLines)
{
if(Line)
{
for(i = Line - 1 ; i < ReviewLines ; i++)
ReviewLineWidths[i] = 0;
}
ReviewWrites("\33[0J\33[3%ldm",RenderPens[1] & 7);
}
ReleaseSemaphore(BufferSemaphore);
}
/* MoveUp(VOID):
*
* Move the review buffer contents up a line.
*/
STATIC VOID
MoveUp(VOID)
{
LONG i;
for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
ReviewLineWidths[i] = ReviewLineWidths[i + 1];
ReviewWrites("\33[S");
ObtainSemaphore(BufferSemaphore);
PrintReviewLine(BufferLines[ReviewTop + ReviewLines],ReviewLines + 1);
ReleaseSemaphore(BufferSemaphore);
}
/* ScrollReview(LONG Top):
*
* Refresh the contents of the review buffer window, reprint
* as few lines as possible.
*/
STATIC VOID __regargs
ScrollReview(LONG Top)
{
LONG i,Last,Line = 0,Delta,Total;
ObtainSemaphore(BufferSemaphore);
ReviewGlobalLines = Lines;
Delta = Top - ReviewTop;
ReviewTop = Top;
if((Last = Top + ReviewLines + 1) >= Lines)
Last = Lines;
Total = Last - Top;
if(ABS(Delta) < ReviewLines)
{
if(!Delta)
{
ReleaseSemaphore(BufferSemaphore);
return;
}
else
{
if(Delta < 0)
{
Last = Top - Delta;
for(i = ReviewMaxLines - 1 ; i > -Delta ; i--)
ReviewLineWidths[i] = ReviewLineWidths[i + Delta];
ReviewWrites("\33[%ldT",-Delta);
}
else
{
for(i = Delta ; i < ReviewMaxLines ; i++)
ReviewLineWidths[i - Delta] = ReviewLineWidths[i];
Top += ReviewLines - Delta;
Line = ReviewLines - Delta;
ReviewWrites("\33[%ldS",Delta);
}
}
}
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
PrintReviewLine(BufferLines[i],++Line);
}
if(Total <= ReviewLines)
ReviewWrites("\33[0J");
ReleaseSemaphore(BufferSemaphore);
}
/* ReviewQuery():
*
* Update the current review buffer window dimensions.
*/
STATIC BYTE
ReviewQuery()
{
struct ConUnit *Unit = (struct ConUnit *)ReviewWriteRequest -> io_Unit;
BYTE Refresh = FALSE;
memset(ReviewLineWidths,0,ReviewMaxLines);
if(ReviewColumns != Unit -> cu_XMax)
{
Refresh = TRUE;
ReviewColumns = Unit -> cu_XMax;
}
if(ReviewLines != Unit -> cu_YMax)
{
if(ReviewTop + ReviewLines == Lines)
{
LONG Delta = ReviewLines - Unit -> cu_YMax;
if(Delta < 0)
ReviewTop += Delta;
else
ReviewTop -= Delta;
if(ReviewTop < 0)
ReviewTop = 0;
}
Refresh = TRUE;
ReviewLines = Unit -> cu_YMax;
}
if(Refresh)
ReviewUpdatePot();
return(TRUE);
}
/* GetReviewChar(BYTE WaitForIt):
*
* Get the next character present at the console read port.
*/
STATIC UBYTE __regargs
GetReviewChar(BYTE WaitForIt)
{
UBYTE Char;
if(!WaitForIt)
{
if(!CheckIO(ReviewReadRequest))
return(0);
}
WaitIO(ReviewReadRequest);
Char = ReviewChar;
ReviewReadRequest -> io_Command = CMD_READ;
ReviewReadRequest -> io_Data = &ReviewChar;
ReviewReadRequest -> io_Length = 1;
SendIO(ReviewReadRequest);
return(Char);
}
/* MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len):
*
* Similar to PrintReviewLine(), but also allows to mark a
* certain word on the line.
*/
STATIC VOID __regargs
MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len)
{
WORD Length = Buffer[-1];
if(Length > ReviewColumns)
Length = ReviewColumns;
ReviewWrites("\33[%ldH",Line);
if(Length <= Column)
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = Buffer;
ReviewWriteRequest -> io_Length = Length;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[0K");
}
else
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = Buffer;
ReviewWriteRequest -> io_Length = Column;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[7;3%ldm",RenderPens[1] & 7);
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = &Buffer[Column];
ReviewWriteRequest -> io_Length = Len;
DoIO(ReviewWriteRequest);
ReviewWrites("\33[0;3%ldm",RenderPens[1] & 7);
if(Column + Len < Length)
{
ReviewWriteRequest -> io_Command = CMD_WRITE;
ReviewWriteRequest -> io_Data = &Buffer[Column + Len];
ReviewWriteRequest -> io_Length = Length - (Column + Len);
DoIO(ReviewWriteRequest);
}
ReviewWrites("\33[0K");
}
}
/* ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh):
*
* Mark a word on the current display.
*/
STATIC VOID __regargs
ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh)
{
STATIC LONG LastMarked = -1;
LONG i,Last,LineIndex = 0;
ReviewGlobalLines = Lines;
ObtainSemaphore(BufferSemaphore);
if((Last = Top + ReviewLines + 1) >= Lines)
Last = Lines;
if(FullRefresh)
{
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
{
if(i != Line)
PrintReviewLine(BufferLines[i],++LineIndex);
else
MarkReviewLine(BufferLines[i],++LineIndex,Column,Len);
}
}
if(LineIndex <= ReviewLines)
ReviewWrites("\33[0J");
}
else
{
if(BufferLines)
{
for(i = Top ; i < Last ; i++)
{
LineIndex++;
if(i == LastMarked)
PrintReviewLine(BufferLines[i],LineIndex);
if(i == Line)
MarkReviewLine(BufferLines[i],LineIndex,Column,Len);
}
}
}
LastMarked = Line;
ReleaseSemaphore(BufferSemaphore);
}
/* ReviewSearch(BYTE Repeat):
*
* Search for a certain word in the text buffer.
*/
STATIC VOID
ReviewSearch(BYTE Repeat)
{
if(Lines)
{
STATIC UBYTE SearchBuffer[256];
LONG LineNumber;
if(!Repeat || !SearchBuffer[0])
{
if(GetSearchString(ReviewWindow,NULL,SearchBuffer,&SearchForward))
{
if(SearchBuffer[0])
{
if(ReviewSearchInfo)
DeleteSearchInfo(ReviewSearchInfo);
ReviewSearchInfo = CreateSearchInfo(SearchBuffer,SearchForward);
}
else
return;
}
else
return;
}
else
{
if(!ReviewSearchInfo)
ReviewSearchInfo = CreateSearchInfo(SearchBuffer,TRUE);
}
if(ReviewSearchInfo)
{
ObtainSemaphore(BufferSemaphore);
LineNumber = SearchTextBuffer(ReviewSearchInfo);
ReleaseSemaphore(BufferSemaphore);
if(LineNumber == -1)
{
RefreshReview(ReviewTop);
MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_DID_NOT_FIND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SearchBuffer);
ReviewSearchInfo -> FoundY = -1;
}
else
{
if(LineNumber < ReviewTop || LineNumber > ReviewTop + ReviewLines)
{
if(LineNumber + ReviewLines > Lines)
{
ReviewTop = Lines - ReviewLines;
if(ReviewTop < 0)
ReviewTop = 0;
}
else
ReviewTop = LineNumber;
ReviewUpdatePot();
ReviewMarkArea(ReviewTop,ReviewSearchInfo -> FoundX,LineNumber,ReviewSearchInfo -> PatternWidth,TRUE);
}
else
ReviewMarkArea(ReviewTop,ReviewSearchInfo -> FoundX,LineNumber,ReviewSearchInfo -> PatternWidth,FALSE);
}
}
}
else
MyEasyRequest(ReviewWindow,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
/* DeleteReview():
*
* Delete the review buffer.
*/
VOID
DeleteReview()
{
CheckItem(MEN_REVIEW_WINDOW,FALSE);
if(ReviewReadRequest)
{
if(ReviewReadRequest -> io_Device)
{
if(!CheckIO(ReviewReadRequest))
AbortIO(ReviewReadRequest);
WaitIO(ReviewReadRequest);
}
FreeVec(ReviewReadRequest);
ReviewReadRequest = NULL;
}
if(ReviewWriteRequest)
{
if(ReviewWriteRequest -> io_Device)
CloseDevice(ReviewWriteRequest);
DeleteIORequest(ReviewWriteRequest);
ReviewWriteRequest = NULL;
}
if(ReviewWindow)
{
PutWindowInfo(WINDOW_REVIEW,ReviewWindow -> LeftEdge,ReviewWindow -> TopEdge,ReviewWindow -> Width,ReviewWindow -> Height);
ClearMenuStrip(ReviewWindow);
CloseWindow(ReviewWindow);
ReviewWindow = NULL;
}
if(ReviewMenuStrip)
{
FreeMenus(ReviewMenuStrip);
ReviewMenuStrip = NULL;
}
ReviewDeleteScroller();
if(ReviewWritePort)
{
DeleteMsgPort(ReviewWritePort);
ReviewWritePort = NULL;
}
if(ReviewPort)
{
DeleteMsgPort(ReviewPort);
ReviewPort = NULL;
}
if(ReviewSearchInfo)
{
DeleteSearchInfo(ReviewSearchInfo);
ReviewSearchInfo = NULL;
}
if(ReviewLineWidths)
{
FreeVec(ReviewLineWidths);
ReviewLineWidths = NULL;
}
}
/* CreateReview():
*
* Create the review buffer.
*/
BYTE
CreateReview()
{
if(ReviewBox . Left == -1)
{
ReviewBox . Left = 0;
ReviewBox . Top = Window -> WScreen -> BarHeight + 1;
ReviewBox . Width = Window -> WScreen -> Width;
ReviewBox . Height = Window -> WScreen -> Height - (Window -> WScreen -> BarHeight + 1);
}
if(ReviewCreateScroller(Window -> WScreen))
{
LocalizeMenu(ReviewMenu,MSG_TERMREVIEW_PROJECT_MEN);
if(ReviewMenuStrip = CreateMenus(ReviewMenu,TAG_DONE))
{
if(LayoutMenus(ReviewMenuStrip,VisualInfo,
GTMN_TextAttr, &UserFont,
GTMN_NewLookMenus, TRUE,
TAG_DONE))
{
LONG Left = 0,
Top = 0,
Width = 0,
Height = 0;
GetWindowInfo(WINDOW_REVIEW,&Left,&Top,&Width,&Height,NULL,Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 10 * CurrentFont -> tf_YSize);
if(ReviewWindow = OpenWindowTags(NULL,
WA_Left, Left,
WA_Top, Top,
WA_Width, Width,
WA_Height, Height,
WA_MinWidth, Window -> WScreen -> WBorLeft + RightBorderWidth + 15 * CurrentFont -> tf_XSize,
WA_MinHeight, Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 2 * CurrentFont -> tf_YSize,
WA_MaxWidth, Window -> WScreen -> Width,
WA_MaxHeight, Window -> WScreen -> Height,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_DepthGadget, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBRight, TRUE,
WA_IDCMP, IDCMP_IDCMPUPDATE | IDCMP_GADGETDOWN | IDCMP_SIZEVERIFY | IDCMP_MOUSEMOVE | IDCMP_MENUPICK,
WA_Title, LocaleString(MSG_TERMREVIEW_REVIEWBUFFER_TXT),
WA_CustomScreen, Window -> WScreen,
WA_SimpleRefresh, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
WA_NewLookMenus, TRUE,
WA_Zoom, &ReviewBox,
WA_Gadgets, Scroller,
TAG_DONE))
{
ReviewMaxLines = (ReviewWindow -> WScreen -> Height - (ReviewWindow -> BorderTop + ReviewWindow -> BorderBottom)) / CurrentFont -> tf_YSize;
if(ReviewLineWidths = (UBYTE *)AllocVec(ReviewMaxLines,MEMF_ANY | MEMF_CLEAR))
{
SetMenuStrip(ReviewWindow,ReviewMenuStrip);
SetFont(ReviewWindow -> RPort,CurrentFont);
if(ReviewWritePort = CreateMsgPort())
{
if(ReviewPort = CreateMsgPort())
{
if(ReviewWriteRequest = CreateIORequest(ReviewPort,sizeof(struct IOStdReq)))
{
if(ReviewReadRequest = (struct IOStdReq *)AllocVec(sizeof(struct IOStdReq),MEMF_ANY | MEMF_CLEAR))
{
ReviewWriteRequest -> io_Data = ReviewWindow;
if(!OpenDevice("console.device",CONU_SNIPMAP,ReviewWriteRequest,CONFLAG_NODRAW_ON_NEWSIZE))
{
CheckItem(MEN_REVIEW_WINDOW,TRUE);
CopyMem(ReviewWriteRequest,ReviewReadRequest,sizeof(struct IOStdReq));
ReviewReadRequest -> io_Message . mn_ReplyPort = ReviewPort;
ReviewWrites("\33[0 p\33[1;11;12{\33[3%ldm",RenderPens[1] & 7);
ReviewQuery();
ObtainSemaphore(BufferSemaphore);
if(ReviewTop == -1 || !Config -> CaptureConfig -> RememberBufferWindow)
{
switch(Config -> CaptureConfig -> OpenBufferWindow)
{
case BUFFER_TOP:
ReviewTop = 0;
break;
case BUFFER_END:
if((ReviewTop = Lines - ReviewLines) < 0)
ReviewTop = 0;
break;
default:
ReviewTop = 0;
break;
}
}
if(ReviewTop > Lines - ReviewLines)
{
if((ReviewTop = Lines - ReviewLines) < 0)
ReviewTop = 0;
}
ReleaseSemaphore(BufferSemaphore);
RefreshReview(ReviewTop);
ReviewUpdatePot();
ReviewReadRequest -> io_Command = CMD_READ;
ReviewReadRequest -> io_Data = &ReviewChar;
ReviewReadRequest -> io_Length = 1;
SendIO(ReviewReadRequest);
ReviewWindow -> Flags &= ~WFLG_RMBTRAP;
return(TRUE);
}
}
}
}
}
}
}
}
}
}
DeleteReview();
return(FALSE);
}
/* UpdateReview():
*
* Update the contents of the review buffer window.
*/
VOID
UpdateReview(BYTE Force)
{
if(ReviewPort)
{
if(Force)
{
if(Lines)
{
if(ReviewTop > 0)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top,--ReviewTop,
TAG_DONE);
}
else
MoveUp();
}
}
else
{
if(Lines >= ReviewGlobalLines && ReviewGlobalLines <= ReviewLines)
RefreshReview(ReviewTop);
}
ReviewGlobalLines = Lines;
if(!Lines)
{
SetGadgetAttrs(Scroller,ReviewWindow,NULL,
PGA_Top, ReviewTop = 0,
PGA_Visible, 1,
PGA_Total, 1,
TAG_DONE);
ReviewWrites("\f\33[3%ldm",RenderPens[1] & 7);
}
else
ReviewUpdatePot();
}
}
/* MoveReview(BYTE Mode):
*
* Move the currently visible review area.
*/
VOID
MoveReview(BYTE Mode)
{
LONG NewTop;
switch(Mode)
{
case REVIEW_MOVE_TOP:
if(ReviewTop)
{
ScrollReview(0);
ReviewUpdatePot();
}
break;
case REVIEW_MOVE_BOTTOM:
NewTop = Lines - ReviewLines;
if(NewTop < 0)
NewTop = 0;
if(ReviewTop != NewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
break;
case REVIEW_MOVE_UP:
ReviewUp(ReviewLines);
break;
case REVIEW_MOVE_DOWN:
ReviewDown(ReviewLines);
break;
}
}
/* HandleReview():
*
* Process console and user input.
*/
BYTE
HandleReview()
{
UBYTE IClass;
UWORD ICode,
IQualifier;
BYTE Result = FALSE;
if(ReviewWindow)
{
struct IntuiMessage *Message;
struct MenuItem *MenuItem;
struct TagItem *TagList;
ULONG IClass;
if(Message = (struct IntuiMessage *)GetMsg(ReviewWindow -> UserPort))
{
IClass = Message -> Class;
ICode = Message -> Code;
IQualifier = Message -> Qualifier;
TagList = (struct TagItem *)Message -> IAddress;
ReplyMsg((struct Message *)Message);
switch(IClass)
{
case IDCMP_IDCMPUPDATE:
switch(GetTagData(GA_ID,0,TagList))
{
case GAD_UP: ReviewUp(1);
break;
case GAD_DOWN: ReviewDown(1);
break;
}
break;
case IDCMP_GADGETDOWN:
case IDCMP_MOUSEMOVE:
if(ReviewGlobalLines > ReviewLines)
{
LONG NewTop;
if(GetAttr(PGA_Top,Scroller,&NewTop))
ScrollReview(NewTop);
}
break;
case IDCMP_MENUPICK:
while(ICode != MENUNULL)
{
MenuItem = ItemAddress(ReviewMenuStrip,ICode);
switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
{
case MEN_SEARCH:
BlockWindow(ReviewWindow);
ReviewSearch(FALSE);
ReleaseWindow(ReviewWindow);
break;
case MEN_REPEAT:
BlockWindow(ReviewWindow);
ReviewSearch(TRUE);
ReleaseWindow(ReviewWindow);
break;
case MEN_QUITBUF:
DeleteReview();
return(TRUE);
case MEN_CLEARBUF:
if(Lines)
{
BlockWindows();
BlockWindow(ReviewWindow);
if(IQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
FreeBuffer();
ReleaseWindow(ReviewWindow);
ReleaseWindows();
return(TRUE);
}
else
{
if(MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
{
FreeBuffer();
ReleaseWindow(ReviewWindow);
ReleaseWindows();
return(TRUE);
}
}
ReleaseWindow(ReviewWindow);
ReleaseWindows();
}
break;
}
ICode = MenuItem -> NextSelect;
}
break;
}
Result = TRUE;
}
}
/* Check for raw input events. */
if(ReviewPort)
{
UBYTE Char;
/* Control sequence available? */
if((Char = GetReviewChar(FALSE)) == CSI)
{
LONG Len;
ULONG Prev;
UBYTE InputBuffer[257];
WORD Count = 0;
/* Try to read the entire sequence. */
while(Char = GetReviewChar(FALSE))
{
SharedBuffer[Count++] = Char;
if(Char != ' ' && Char != ';' && (Char < '0' || Char > '9'))
break;
}
/* Provide termination. */
SharedBuffer[Count] = 0;
/* Raw event? */
if(Char == '|')
SplitEventReport(SharedBuffer,Count,&IClass,&ICode,&IQualifier,&Prev);
else
IClass = 0;
if(!strcmp(SharedBuffer,"0 v"))
{
if(!ClipInput)
{
if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
ClipInput = TRUE;
else
ClipInput = FALSE;
ClipXerox = FALSE;
}
if(ClipInput)
{
/* Is a send-delay enabled? */
if(Config -> ClipConfig -> CharDelay || Config -> ClipConfig -> LineDelay)
{
while((Len = GetClip(InputBuffer,256,FALSE)) > 0)
{
WORD i;
/* Run down the buffer... */
for(i = 0 ; i < Len ; i++)
{
SerWrite(&InputBuffer[i],1);
/* What kind of delay
* are we to provide?
*/
if(InputBuffer[i] == '\r')
{
if(Config -> ClipConfig -> LineDelay)
WaitTime(Config -> ClipConfig -> LineDelay / 100,(Config -> ClipConfig -> LineDelay % 100) * 10000);
}
else
{
if(Config -> ClipConfig -> CharDelay)
WaitTime(Config -> ClipConfig -> CharDelay / 100,(Config -> ClipConfig -> CharDelay % 100) * 10000);
}
}
}
}
else
{
while((Len = GetClip(InputBuffer,256,FALSE)) > 0)
SerWrite(InputBuffer,Len);
}
CloseClip();
ClipInput = ClipPrefix = FALSE;
}
}
else
{
/* Check the event type. */
switch(IClass)
{
case 1:
/* Convert the event... */
Char = ConvertTheKey(InputBuffer,&Len,ICode,IQualifier,Prev);
/* Lather, rinse, process as usual. */
if(Len)
{
switch(CharType[Char])
{
case CHAR_HELP:
GuideDisplay(CONTEXT_TEXTBUFFER);
Len = 0;
break;
case CHAR_CURSOR:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
if(Char == CUP || Char == CDN)
{
/* Find the approriate qualifier. */
if(IQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
if(Char == CUP)
ReviewUp(ReviewLines);
else
ReviewDown(ReviewLines);
}
else
{
if(IQualifier & (IEQUALIFIER_CONTROL | IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
if(Char == CUP)
{
if(ReviewTop)
{
ScrollReview(0);
ReviewUpdatePot();
}
}
else
{
LONG NewTop = Lines - ReviewLines;
if(NewTop < 0)
NewTop = 0;
if(NewTop != ReviewTop)
{
ScrollReview(NewTop);
ReviewUpdatePot();
}
}
}
else
{
if(Char == CUP)
ReviewUp(1);
else
ReviewDown(1);
}
}
}
Len = 0;
break;
/* Any function key pressed? */
case CHAR_FUNCTION:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
if(IQualifier & IEQUALIFIER_CONTROL)
SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
else
{
if(IQualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
else
{
if(IQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
else
SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
}
}
Len = 0;
break;
/* Anything else? */
default:
if(Len == 1 && (IQualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
{
STATIC STRPTR ApplicationTable[20][2] =
{
"0", "\033Op",
"1", "\033Oq",
"2", "\033Or",
"3", "\033Os",
"4", "\033Ot",
"5", "\033Ou",
"6", "\033Ov",
"7", "\033Ow",
"8", "\033Ox",
"9", "\033Oy",
"-", "\033Om",
"+", "\033Ol", /* This should really be a comma */
".", "\033On",
"[", "\033OP",
"{", "\033OP",
"]", "\033OQ",
"}", "\033OQ",
"/", "\033OR",
"*", "\033OS",
"\r", "\033OM"
};
WORD i;
for(i = 0 ; i < 20 ; i++)
{
if(Char == ApplicationTable[i][0][0])
{
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
SerWrite(ApplicationTable[i][1],strlen(ApplicationTable[i][1]));
Len = 0;
break;
}
}
}
break;
}
/* Any characters to send? */
if(Len)
{
STRPTR Buffer = InputBuffer;
UBYTE Mask,
c;
/* Strip the high order bit? */
if(Config -> SerialConfig -> StripBit8)
Mask = 0x7F;
else
Mask = 0xFF;
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
while(Len--)
{
switch(CharType[c = (*Buffer++) & Mask])
{
case CHAR_ENTER:
if(Status == STATUS_HOLDING)
DoBeep();
else
{
switch(Config -> TerminalConfig -> SendLF)
{
case LF_ASLF:
SerWrite("\n",1);
break;
case LF_ASLFCR:
SerWrite("\n\r",2);
break;
}
}
break;
case CHAR_RETURN:
if(Status == STATUS_HOLDING)
DoBeep();
else
{
switch(Config -> TerminalConfig -> SendCR)
{
case CR_ASCR:
SerWrite("\r",1);
break;
case CR_ASCRLF:
SerWrite("\r\n",2);
break;
}
}
break;
/* Stop in/output. */
case CHAR_XON:
if(Status == STATUS_HOLDING)
DoBeep();
else
{
if(Config -> SerialConfig -> xONxOFF)
Status = STATUS_HOLDING;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
}
break;
/* Restart in/output. */
case CHAR_XOFF:
if(Status == STATUS_HOLDING)
Status = STATUS_READY;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
break;
/* Any other character. */
case CHAR_VANILLA:
if(Status == STATUS_HOLDING)
DoBeep();
else
{
if(Config -> TerminalConfig -> FontMode == FONT_IBM)
{
/* Convert special
* Amiga characters into
* alien IBM dialect.
*/
if(IBMConversion[c])
SerWrite(&IBMConversion[c],1);
else
SerWrite(&c,1);
}
else
SerWrite(&c,1);
}
break;
}
}
}
}
break;
case 11:
DeleteReview();
return(Result);
case 12:
if(ReviewQuery())
RefreshReview(ReviewTop);
break;
}
}
return(TRUE);
}
}
return(Result);
}